{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import random,datetime\n",
    "from bisect import bisect_left\n",
    "from math import exp"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "def _mutate_custom(parent, custom_mutate, get_fitness):\n",
    "    childGenes = parent.Genes[:]\n",
    "    custom_mutate(childGenes)\n",
    "    fitness = get_fitness(childGenes)\n",
    "    return Chromosome(childGenes, fitness)\n",
    "\n",
    "\n",
    "def get_best(get_fitness, targetLen, optimalFitness, geneSet, display,\n",
    "             custom_mutate=None, custom_create=None, maxAge=None):\n",
    "    if custom_mutate is None:\n",
    "        def fnMutate(parent):\n",
    "            return _mutate(parent, geneSet, get_fitness)\n",
    "    else:\n",
    "        def fnMutate(parent):\n",
    "            return _mutate_custom(parent, custom_mutate, get_fitness)\n",
    "\n",
    "    if custom_create is None:\n",
    "        def fnGenerateParent():\n",
    "            return _generate_parent(targetLen, geneSet, get_fitness)\n",
    "    else:\n",
    "        def fnGenerateParent():\n",
    "            genes = custom_create()\n",
    "            return Chromosome(genes, get_fitness(genes))\n",
    "\n",
    "    for improvement in _get_improvement(fnMutate, fnGenerateParent, maxAge):\n",
    "        display(improvement)\n",
    "        if not optimalFitness > improvement.Fitness:\n",
    "            return improvement\n",
    "\n",
    "\n",
    "def _get_improvement(new_child, generate_parent, maxAge):\n",
    "    parent = bestParent = generate_parent()\n",
    "    yield bestParent\n",
    "    historicalFitnesses = [bestParent.Fitness]\n",
    "    while True:\n",
    "        child = new_child(parent)\n",
    "        if parent.Fitness > child.Fitness:\n",
    "            if maxAge is None:\n",
    "                continue\n",
    "            parent.Age += 1\n",
    "            if maxAge > parent.Age:\n",
    "                continue\n",
    "            index = bisect_left(historicalFitnesses, child.Fitness, 0,\n",
    "                                len(historicalFitnesses))\n",
    "            proportionSimilar = index / len(historicalFitnesses)\n",
    "            if random.random() < exp(-proportionSimilar):\n",
    "                parent = child\n",
    "                continue\n",
    "            bestParent.Age = 0\n",
    "            parent = bestParent\n",
    "            continue\n",
    "        if not child.Fitness > parent.Fitness:\n",
    "            # same fitness\n",
    "            child.Age = parent.Age + 1\n",
    "            parent = child\n",
    "            continue\n",
    "        child.Age = 0\n",
    "        parent = child\n",
    "        if child.Fitness > bestParent.Fitness:\n",
    "            bestParent = child\n",
    "            yield bestParent\n",
    "            historicalFitnesses.append(bestParent.Fitness)\n",
    "\n",
    "\n",
    "class Chromosome:\n",
    "    def __init__(self, genes, fitness):\n",
    "        self.Genes = genes\n",
    "        self.Fitness = fitness\n",
    "        self.Age = 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_fitness(genes, validationRules):\n",
    "    try:\n",
    "        firstFailingRule = next(rule for rule in validationRules\n",
    "                                if genes[rule.Index] == genes[rule.OtherIndex])\n",
    "    except StopIteration:\n",
    "        fitness = 100\n",
    "    else:\n",
    "        fitness = (1 + index_row(firstFailingRule.OtherIndex)) * 10 \\\n",
    "                  + (1 + index_column(firstFailingRule.OtherIndex))\n",
    "    return fitness"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "def display(candidate, startTime):\n",
    "    timeDiff = datetime.datetime.now() - startTime\n",
    "\n",
    "    for row in range(9):\n",
    "        line = ' | '.join(\n",
    "            ' '.join(str(i)\n",
    "                     for i in candidate.Genes[row * 9 + i:row * 9 + i + 3])\n",
    "            for i in [0, 3, 6])\n",
    "        print(\"\", line)\n",
    "        if row < 8 and row % 3 == 2:\n",
    "            print(\" ----- + ----- + -----\")\n",
    "    print(\" - = -   - = -   - = - {}\\t{}\\n\"\n",
    "          .format(candidate.Fitness, timeDiff))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "def mutate(genes, validationRules):\n",
    "    selectedRule = next(rule for rule in validationRules\n",
    "                        if genes[rule.Index] == genes[rule.OtherIndex])\n",
    "    if selectedRule is None:\n",
    "        return\n",
    "\n",
    "    if index_row(selectedRule.OtherIndex) % 3 == 2 \\\n",
    "            and random.randint(0, 10) == 0:\n",
    "        sectionStart = section_start(selectedRule.Index)\n",
    "        current = selectedRule.OtherIndex\n",
    "        while selectedRule.OtherIndex == current:\n",
    "            shuffle_in_place(genes, sectionStart, 80)\n",
    "            selectedRule = next(rule for rule in validationRules\n",
    "                                if genes[rule.Index] == genes[rule.OtherIndex])\n",
    "        return\n",
    "    row = index_row(selectedRule.OtherIndex)\n",
    "    start = row * 9\n",
    "    indexA = selectedRule.OtherIndex\n",
    "    indexB = random.randrange(start, len(genes))\n",
    "    genes[indexA], genes[indexB] = genes[indexB], genes[indexA]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "def shuffle_in_place(genes, first, last):\n",
    "    while first < last:\n",
    "        index = random.randint(first, last)\n",
    "        genes[first], genes[index] = genes[index], genes[first]\n",
    "        first += 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "def build_validation_rules():\n",
    "    rules = []\n",
    "    for index in range(80):\n",
    "        itsRow = index_row(index)\n",
    "        itsColumn = index_column(index)\n",
    "        itsSection = row_column_section(itsRow, itsColumn)\n",
    "\n",
    "        for index2 in range(index + 1, 81):\n",
    "            otherRow = index_row(index2)\n",
    "            otherColumn = index_column(index2)\n",
    "            otherSection = row_column_section(otherRow, otherColumn)\n",
    "            if itsRow == otherRow or \\\n",
    "                            itsColumn == otherColumn or \\\n",
    "                            itsSection == otherSection:\n",
    "                rules.append(Rule(index, index2))\n",
    "\n",
    "    rules.sort(key=lambda x: x.OtherIndex * 100 + x.Index)\n",
    "    return rules\n",
    "\n",
    "\n",
    "def index_row(index):\n",
    "    return int(index / 9)\n",
    "\n",
    "\n",
    "def index_column(index):\n",
    "    return int(index % 9)\n",
    "\n",
    "\n",
    "def row_column_section(row, column):\n",
    "    return int(row / 3) * 3 + int(column / 3)\n",
    "\n",
    "\n",
    "def index_section(index):\n",
    "    return row_column_section(index_row(index), index_column(index))\n",
    "\n",
    "\n",
    "def section_start(index):\n",
    "    return int((index_row(index) % 9) / 3) * 27 + int(\n",
    "        index_column(index) / 3) * 3\n",
    "\n",
    "\n",
    "class Rule:\n",
    "    def __init__(self, it, other):\n",
    "        if it > other:\n",
    "            it, other = other, it\n",
    "        self.Index = it\n",
    "        self.OtherIndex = other\n",
    "\n",
    "    def __eq__(self, other):\n",
    "        return self.Index == other.Index and \\\n",
    "               self.OtherIndex == other.OtherIndex\n",
    "\n",
    "    def __hash__(self):\n",
    "        return self.Index * 100 + self.OtherIndex"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "def test():\n",
    "    geneset = [i for i in range(1, 9 + 1)]\n",
    "    startTime = datetime.datetime.now()\n",
    "    optimalValue = 100\n",
    "\n",
    "    def fnDisplay(candidate):\n",
    "        display(candidate, startTime)\n",
    "\n",
    "    validationRules = build_validation_rules()\n",
    "\n",
    "    def fnGetFitness(genes):\n",
    "        return get_fitness(genes, validationRules)\n",
    "\n",
    "    def fnCreate():\n",
    "        return random.sample(geneset * 9, 81)\n",
    "\n",
    "    def fnMutate(genes):\n",
    "        mutate(genes, validationRules)\n",
    "\n",
    "    best = get_best(fnGetFitness, None, optimalValue, None,\n",
    "                                fnDisplay, fnMutate, fnCreate, maxAge=50)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " 2 3 1 | 5 7 9 | 3 4 7\n",
      " 9 4 6 | 8 7 7 | 8 1 2\n",
      " 2 9 5 | 6 5 4 | 3 2 4\n",
      " ----- + ----- + -----\n",
      " 7 1 1 | 9 6 2 | 1 5 8\n",
      " 3 7 5 | 3 7 8 | 9 4 7\n",
      " 6 4 9 | 4 9 1 | 7 6 2\n",
      " ----- + ----- + -----\n",
      " 8 1 6 | 4 8 3 | 3 1 4\n",
      " 9 5 6 | 5 2 3 | 9 2 5\n",
      " 6 2 8 | 8 5 6 | 8 3 1\n",
      " - = -   - = -   - = - 17\t0:00:00.004985\n",
      "\n",
      " 2 3 1 | 5 7 9 | 8 4 3\n",
      " 9 4 6 | 8 7 7 | 8 1 2\n",
      " 2 9 5 | 6 5 4 | 3 2 4\n",
      " ----- + ----- + -----\n",
      " 7 1 1 | 9 6 2 | 3 5 8\n",
      " 3 7 5 | 3 7 8 | 9 4 7\n",
      " 6 4 9 | 4 9 1 | 7 6 2\n",
      " ----- + ----- + -----\n",
      " 2 1 6 | 4 8 7 | 3 1 4\n",
      " 9 5 6 | 5 2 3 | 9 2 5\n",
      " 6 3 8 | 8 5 6 | 8 1 1\n",
      " - = -   - = -   - = - 19\t0:00:00.005999\n",
      "\n",
      " 2 3 1 | 5 7 9 | 8 4 6\n",
      " 9 4 6 | 8 7 7 | 8 5 2\n",
      " 2 9 5 | 6 5 4 | 3 2 7\n",
      " ----- + ----- + -----\n",
      " 7 1 1 | 9 6 2 | 3 3 8\n",
      " 3 7 5 | 3 7 8 | 9 4 7\n",
      " 6 4 4 | 4 9 1 | 7 6 2\n",
      " ----- + ----- + -----\n",
      " 2 1 6 | 9 8 2 | 3 9 4\n",
      " 1 5 6 | 5 1 3 | 9 2 5\n",
      " 6 3 8 | 8 5 4 | 8 1 1\n",
      " - = -   - = -   - = - 25\t0:00:00.006980\n",
      "\n",
      " 2 3 1 | 5 7 9 | 8 4 6\n",
      " 9 4 6 | 8 1 7 | 5 5 2\n",
      " 2 9 8 | 6 5 4 | 3 2 7\n",
      " ----- + ----- + -----\n",
      " 7 1 1 | 9 6 2 | 3 3 8\n",
      " 3 7 5 | 3 7 8 | 9 4 7\n",
      " 6 4 4 | 4 9 1 | 7 6 2\n",
      " ----- + ----- + -----\n",
      " 2 1 6 | 9 8 2 | 3 9 4\n",
      " 1 5 6 | 5 1 3 | 9 2 7\n",
      " 6 3 8 | 8 5 4 | 8 5 1\n",
      " - = -   - = -   - = - 26\t0:00:00.007976\n",
      "\n",
      " 2 3 1 | 5 7 9 | 8 4 6\n",
      " 9 4 6 | 8 1 2 | 5 5 2\n",
      " 2 9 8 | 6 5 4 | 3 2 7\n",
      " ----- + ----- + -----\n",
      " 7 1 1 | 9 6 2 | 3 3 8\n",
      " 3 7 5 | 3 7 8 | 9 4 7\n",
      " 6 4 4 | 4 9 1 | 7 6 2\n",
      " ----- + ----- + -----\n",
      " 2 1 6 | 7 8 2 | 3 9 4\n",
      " 1 5 6 | 5 1 3 | 9 9 7\n",
      " 6 3 8 | 8 5 4 | 8 5 1\n",
      " - = -   - = -   - = - 28\t0:00:00.015955\n",
      "\n",
      " 2 3 1 | 5 7 9 | 8 4 6\n",
      " 9 4 6 | 8 1 2 | 5 7 2\n",
      " 2 9 8 | 6 5 4 | 3 2 7\n",
      " ----- + ----- + -----\n",
      " 4 1 1 | 9 6 2 | 3 3 8\n",
      " 3 7 5 | 3 7 8 | 9 5 7\n",
      " 6 4 4 | 4 9 1 | 7 6 2\n",
      " ----- + ----- + -----\n",
      " 2 1 6 | 7 8 2 | 3 9 4\n",
      " 1 5 6 | 5 1 3 | 9 9 7\n",
      " 6 3 8 | 8 5 4 | 8 5 1\n",
      " - = -   - = -   - = - 29\t0:00:00.016953\n",
      "\n",
      " 2 3 1 | 5 7 9 | 8 4 6\n",
      " 9 4 6 | 8 1 2 | 5 7 3\n",
      " 2 9 8 | 4 5 5 | 3 7 2\n",
      " ----- + ----- + -----\n",
      " 6 4 9 | 9 6 2 | 3 4 8\n",
      " 3 7 5 | 3 7 8 | 9 1 2\n",
      " 6 1 1 | 4 9 1 | 7 6 2\n",
      " ----- + ----- + -----\n",
      " 2 6 6 | 7 8 4 | 3 5 1\n",
      " 6 7 5 | 4 1 3 | 9 9 7\n",
      " 5 3 8 | 2 5 4 | 8 8 1\n",
      " - = -   - = -   - = - 31\t0:00:00.018947\n",
      "\n",
      " 2 3 1 | 5 7 9 | 8 4 6\n",
      " 9 4 6 | 8 1 2 | 5 7 3\n",
      " 8 4 8 | 4 5 5 | 3 7 2\n",
      " ----- + ----- + -----\n",
      " 6 2 9 | 9 6 2 | 3 4 8\n",
      " 3 7 5 | 3 7 8 | 9 1 2\n",
      " 6 1 1 | 4 9 1 | 7 6 2\n",
      " ----- + ----- + -----\n",
      " 2 6 6 | 7 9 4 | 3 5 1\n",
      " 6 7 5 | 4 1 3 | 9 9 7\n",
      " 5 3 8 | 2 5 4 | 8 8 1\n",
      " - = -   - = -   - = - 32\t0:00:00.019946\n",
      "\n",
      " 2 3 1 | 5 7 9 | 8 4 6\n",
      " 9 4 6 | 8 1 2 | 5 7 3\n",
      " 8 7 8 | 4 5 5 | 3 7 2\n",
      " ----- + ----- + -----\n",
      " 6 2 9 | 9 6 2 | 3 4 8\n",
      " 3 7 5 | 3 8 4 | 9 1 2\n",
      " 6 1 1 | 4 9 1 | 7 6 2\n",
      " ----- + ----- + -----\n",
      " 2 6 6 | 7 9 4 | 3 5 1\n",
      " 6 7 5 | 4 1 3 | 9 9 7\n",
      " 5 3 8 | 2 5 4 | 8 8 1\n",
      " - = -   - = -   - = - 33\t0:00:00.020940\n",
      "\n",
      " 2 3 1 | 5 7 9 | 8 4 6\n",
      " 9 4 6 | 8 1 2 | 5 7 3\n",
      " 8 7 5 | 4 5 5 | 3 7 2\n",
      " ----- + ----- + -----\n",
      " 6 2 9 | 9 6 2 | 3 4 8\n",
      " 3 7 5 | 3 8 4 | 9 1 2\n",
      " 6 1 1 | 4 9 1 | 7 6 2\n",
      " ----- + ----- + -----\n",
      " 2 6 6 | 7 9 4 | 3 5 1\n",
      " 6 7 8 | 4 1 3 | 9 9 7\n",
      " 5 3 8 | 2 5 4 | 8 8 1\n",
      " - = -   - = -   - = - 35\t0:00:00.021939\n",
      "\n",
      " 2 3 1 | 5 7 9 | 8 4 6\n",
      " 9 4 6 | 8 1 2 | 5 7 3\n",
      " 8 7 5 | 4 6 5 | 3 7 2\n",
      " ----- + ----- + -----\n",
      " 6 2 9 | 9 6 2 | 3 4 8\n",
      " 3 7 5 | 3 8 4 | 9 1 2\n",
      " 6 1 1 | 4 9 1 | 7 9 2\n",
      " ----- + ----- + -----\n",
      " 2 6 6 | 7 5 4 | 3 5 1\n",
      " 6 7 8 | 4 1 3 | 9 9 7\n",
      " 5 3 8 | 2 5 4 | 8 8 1\n",
      " - = -   - = -   - = - 36\t0:00:00.023932\n",
      "\n",
      " 2 3 1 | 5 7 9 | 8 4 6\n",
      " 9 4 6 | 8 1 2 | 5 7 3\n",
      " 8 7 5 | 4 6 3 | 3 7 2\n",
      " ----- + ----- + -----\n",
      " 6 2 9 | 9 6 2 | 3 7 8\n",
      " 1 7 5 | 3 8 1 | 9 6 2\n",
      " 6 1 7 | 4 9 1 | 4 9 2\n",
      " ----- + ----- + -----\n",
      " 2 5 5 | 4 5 4 | 3 5 1\n",
      " 6 7 8 | 4 1 3 | 9 9 7\n",
      " 5 3 8 | 2 6 4 | 8 8 1\n",
      " - = -   - = -   - = - 37\t0:00:00.025927\n",
      "\n",
      " 2 3 1 | 5 7 9 | 8 4 6\n",
      " 9 4 6 | 8 1 2 | 5 7 3\n",
      " 8 7 5 | 4 6 3 | 2 7 2\n",
      " ----- + ----- + -----\n",
      " 6 3 9 | 9 6 2 | 3 7 8\n",
      " 1 7 5 | 3 8 1 | 9 6 2\n",
      " 6 1 7 | 4 9 1 | 4 9 2\n",
      " ----- + ----- + -----\n",
      " 2 5 5 | 4 5 4 | 3 5 1\n",
      " 6 7 8 | 4 1 3 | 9 9 7\n",
      " 5 3 8 | 2 6 4 | 8 8 1\n",
      " - = -   - = -   - = - 38\t0:00:00.026925\n",
      "\n",
      " 2 3 1 | 5 7 9 | 8 4 6\n",
      " 9 4 6 | 8 1 2 | 5 7 3\n",
      " 8 7 5 | 4 6 3 | 2 1 2\n",
      " ----- + ----- + -----\n",
      " 6 3 9 | 9 6 2 | 3 7 8\n",
      " 7 7 5 | 3 8 1 | 9 6 2\n",
      " 6 1 7 | 4 9 1 | 4 9 2\n",
      " ----- + ----- + -----\n",
      " 2 5 5 | 4 5 4 | 3 5 1\n",
      " 6 7 8 | 4 1 3 | 9 9 7\n",
      " 5 3 8 | 2 6 4 | 8 8 1\n",
      " - = -   - = -   - = - 39\t0:00:00.027921\n",
      "\n",
      " 2 3 1 | 5 7 9 | 8 4 6\n",
      " 9 4 6 | 8 1 2 | 5 7 3\n",
      " 8 7 5 | 4 6 3 | 2 1 9\n",
      " ----- + ----- + -----\n",
      " 6 3 9 | 9 6 2 | 3 7 8\n",
      " 7 2 5 | 3 4 1 | 1 6 2\n",
      " 6 1 7 | 4 9 1 | 4 9 2\n",
      " ----- + ----- + -----\n",
      " 8 5 5 | 1 5 4 | 3 5 1\n",
      " 7 7 8 | 4 2 3 | 9 9 7\n",
      " 5 3 8 | 2 6 4 | 8 8 6\n",
      " - = -   - = -   - = - 42\t0:00:00.029915\n",
      "\n",
      " 2 3 1 | 5 7 9 | 8 4 6\n",
      " 9 4 6 | 8 1 2 | 5 7 3\n",
      " 8 7 5 | 4 6 3 | 2 1 9\n",
      " ----- + ----- + -----\n",
      " 6 2 9 | 9 6 2 | 3 7 8\n",
      " 7 3 5 | 3 4 1 | 1 6 2\n",
      " 6 1 7 | 4 9 1 | 4 9 2\n",
      " ----- + ----- + -----\n",
      " 8 5 5 | 1 5 4 | 3 5 1\n",
      " 7 7 8 | 4 2 3 | 9 9 7\n",
      " 5 3 8 | 2 6 4 | 8 8 6\n",
      " - = -   - = -   - = - 44\t0:00:00.029915\n",
      "\n",
      " 2 3 1 | 5 7 9 | 8 4 6\n",
      " 9 4 6 | 8 1 2 | 5 7 3\n",
      " 8 7 5 | 4 6 3 | 2 1 9\n",
      " ----- + ----- + -----\n",
      " 6 2 8 | 9 6 2 | 3 7 8\n",
      " 7 3 5 | 3 4 1 | 1 6 2\n",
      " 6 1 7 | 4 9 1 | 4 9 2\n",
      " ----- + ----- + -----\n",
      " 8 5 5 | 1 5 4 | 3 5 1\n",
      " 7 7 8 | 4 2 3 | 9 9 7\n",
      " 5 3 9 | 2 6 4 | 8 8 6\n",
      " - = -   - = -   - = - 45\t0:00:00.030912\n",
      "\n",
      " 2 3 1 | 5 7 9 | 8 4 6\n",
      " 9 4 6 | 8 1 2 | 5 7 3\n",
      " 8 7 5 | 4 6 3 | 2 1 9\n",
      " ----- + ----- + -----\n",
      " 6 2 8 | 9 4 2 | 3 1 8\n",
      " 7 3 5 | 3 9 2 | 1 6 2\n",
      " 6 1 7 | 4 9 1 | 4 7 6\n",
      " ----- + ----- + -----\n",
      " 8 5 5 | 1 5 4 | 3 5 1\n",
      " 7 7 8 | 4 2 3 | 9 9 7\n",
      " 5 3 9 | 2 6 4 | 8 8 6\n",
      " - = -   - = -   - = - 46\t0:00:00.031910\n",
      "\n",
      " 2 3 1 | 5 7 9 | 8 4 6\n",
      " 9 4 6 | 8 1 2 | 5 7 3\n",
      " 8 7 5 | 4 6 3 | 2 1 9\n",
      " ----- + ----- + -----\n",
      " 6 2 8 | 9 4 1 | 3 1 6\n",
      " 7 3 5 | 9 9 2 | 8 6 2\n",
      " 6 1 7 | 4 9 1 | 4 7 8\n",
      " ----- + ----- + -----\n",
      " 8 5 5 | 1 5 4 | 3 5 1\n",
      " 7 7 8 | 4 2 3 | 9 9 7\n",
      " 5 3 2 | 2 6 4 | 3 8 6\n",
      " - = -   - = -   - = - 48\t0:00:00.031910\n",
      "\n",
      " 2 3 1 | 5 7 9 | 8 4 6\n",
      " 9 4 6 | 8 1 2 | 5 7 3\n",
      " 8 7 5 | 4 6 3 | 2 1 9\n",
      " ----- + ----- + -----\n",
      " 6 2 8 | 9 4 1 | 3 5 6\n",
      " 7 3 5 | 9 9 2 | 8 6 2\n",
      " 6 1 7 | 4 9 1 | 4 7 8\n",
      " ----- + ----- + -----\n",
      " 8 5 5 | 1 5 4 | 3 5 1\n",
      " 7 7 8 | 4 2 3 | 9 9 7\n",
      " 1 3 2 | 2 6 4 | 3 8 6\n",
      " - = -   - = -   - = - 49\t0:00:00.032912\n",
      "\n",
      " 2 3 1 | 5 7 9 | 8 4 6\n",
      " 9 4 6 | 8 1 2 | 5 7 3\n",
      " 8 7 5 | 4 6 3 | 2 1 9\n",
      " ----- + ----- + -----\n",
      " 6 2 8 | 9 4 1 | 3 5 7\n",
      " 7 3 5 | 9 9 2 | 8 6 2\n",
      " 6 1 1 | 4 9 1 | 4 7 8\n",
      " ----- + ----- + -----\n",
      " 8 5 5 | 1 5 4 | 3 5 6\n",
      " 7 7 8 | 4 2 3 | 9 9 7\n",
      " 1 3 2 | 2 6 4 | 3 8 6\n",
      " - = -   - = -   - = - 52\t0:00:00.033916\n",
      "\n",
      " 2 3 1 | 5 7 9 | 8 4 6\n",
      " 9 4 6 | 8 1 2 | 5 7 3\n",
      " 8 7 5 | 4 6 3 | 2 1 9\n",
      " ----- + ----- + -----\n",
      " 6 2 8 | 9 4 1 | 3 5 7\n",
      " 7 1 5 | 9 9 2 | 8 6 2\n",
      " 6 1 7 | 4 9 1 | 3 7 8\n",
      " ----- + ----- + -----\n",
      " 8 5 5 | 1 5 4 | 3 5 6\n",
      " 7 2 8 | 4 2 3 | 9 9 7\n",
      " 1 3 4 | 2 6 4 | 3 8 6\n",
      " - = -   - = -   - = - 53\t0:00:00.035909\n",
      "\n",
      " 2 3 1 | 5 7 9 | 8 4 6\n",
      " 9 4 6 | 8 1 2 | 5 7 3\n",
      " 8 7 5 | 4 6 3 | 2 1 9\n",
      " ----- + ----- + -----\n",
      " 6 2 8 | 9 4 1 | 3 5 7\n",
      " 7 1 3 | 9 9 2 | 8 6 2\n",
      " 6 1 7 | 4 9 1 | 3 7 8\n",
      " ----- + ----- + -----\n",
      " 8 5 5 | 1 5 4 | 3 5 6\n",
      " 7 7 8 | 4 2 2 | 9 9 5\n",
      " 1 3 4 | 2 6 4 | 3 8 6\n",
      " - = -   - = -   - = - 54\t0:00:00.039892\n",
      "\n",
      " 2 3 1 | 5 7 9 | 8 4 6\n",
      " 9 4 6 | 8 1 2 | 5 7 3\n",
      " 8 7 5 | 4 6 3 | 2 1 9\n",
      " ----- + ----- + -----\n",
      " 6 2 8 | 9 4 1 | 3 5 7\n",
      " 7 1 3 | 6 4 2 | 8 6 2\n",
      " 9 1 7 | 4 9 1 | 3 7 8\n",
      " ----- + ----- + -----\n",
      " 8 5 5 | 1 5 4 | 3 5 6\n",
      " 7 9 8 | 4 2 2 | 9 9 5\n",
      " 1 3 7 | 2 6 4 | 3 8 6\n",
      " - = -   - = -   - = - 55\t0:00:00.040890\n",
      "\n",
      " 2 3 1 | 5 7 9 | 8 4 6\n",
      " 9 4 6 | 8 1 2 | 5 7 3\n",
      " 8 7 5 | 4 6 3 | 2 1 9\n",
      " ----- + ----- + -----\n",
      " 6 2 8 | 9 4 1 | 3 5 7\n",
      " 7 1 3 | 6 2 2 | 8 6 1\n",
      " 9 1 7 | 4 9 1 | 3 7 8\n",
      " ----- + ----- + -----\n",
      " 8 5 5 | 4 5 4 | 3 5 6\n",
      " 7 9 8 | 4 2 2 | 9 9 5\n",
      " 1 3 7 | 2 6 4 | 3 8 6\n",
      " - = -   - = -   - = - 56\t0:00:00.044879\n",
      "\n",
      " 2 3 1 | 5 7 9 | 8 4 6\n",
      " 9 4 6 | 8 1 2 | 5 7 3\n",
      " 8 7 5 | 4 6 3 | 2 1 9\n",
      " ----- + ----- + -----\n",
      " 6 2 8 | 9 4 1 | 3 5 7\n",
      " 7 1 3 | 6 2 8 | 8 6 1\n",
      " 9 1 7 | 4 9 1 | 3 7 2\n",
      " ----- + ----- + -----\n",
      " 8 5 5 | 4 5 4 | 3 5 6\n",
      " 7 9 8 | 4 2 2 | 9 9 5\n",
      " 1 3 7 | 2 6 4 | 3 8 6\n",
      " - = -   - = -   - = - 57\t0:00:00.045875\n",
      "\n",
      " 2 3 1 | 5 7 9 | 8 4 6\n",
      " 9 4 6 | 8 1 2 | 5 7 3\n",
      " 8 7 5 | 4 6 3 | 2 1 9\n",
      " ----- + ----- + -----\n",
      " 6 2 8 | 9 4 1 | 3 5 7\n",
      " 7 1 3 | 6 2 8 | 4 6 1\n",
      " 9 1 7 | 4 9 1 | 3 7 2\n",
      " ----- + ----- + -----\n",
      " 8 5 5 | 4 5 8 | 3 5 6\n",
      " 7 9 8 | 4 2 2 | 9 9 5\n",
      " 1 3 7 | 2 6 4 | 3 8 6\n",
      " - = -   - = -   - = - 58\t0:00:00.047869\n",
      "\n",
      " 2 3 1 | 5 7 9 | 8 4 6\n",
      " 9 4 6 | 8 1 2 | 5 7 3\n",
      " 8 7 5 | 4 6 3 | 2 1 9\n",
      " ----- + ----- + -----\n",
      " 6 2 8 | 9 4 1 | 3 5 7\n",
      " 5 1 3 | 6 2 8 | 4 9 1\n",
      " 9 1 2 | 4 4 1 | 1 7 7\n",
      " ----- + ----- + -----\n",
      " 6 6 5 | 8 5 8 | 3 2 2\n",
      " 7 9 5 | 7 2 3 | 9 9 5\n",
      " 4 7 8 | 3 6 4 | 3 8 6\n",
      " - = -   - = -   - = - 59\t0:00:00.053853\n",
      "\n",
      " 2 3 1 | 5 7 9 | 8 4 6\n",
      " 9 4 6 | 8 1 2 | 5 7 3\n",
      " 8 7 5 | 4 6 3 | 2 1 9\n",
      " ----- + ----- + -----\n",
      " 6 2 8 | 9 4 1 | 3 5 7\n",
      " 7 5 3 | 6 2 8 | 4 9 1\n",
      " 9 1 2 | 4 4 1 | 6 7 7\n",
      " ----- + ----- + -----\n",
      " 5 6 5 | 1 5 8 | 3 2 2\n",
      " 2 9 8 | 7 6 3 | 9 9 5\n",
      " 3 7 8 | 4 4 1 | 3 8 6\n",
      " - = -   - = -   - = - 61\t0:00:00.055883\n",
      "\n",
      " 2 3 1 | 5 7 9 | 8 4 6\n",
      " 9 4 6 | 8 1 2 | 5 7 3\n",
      " 8 7 5 | 4 6 3 | 2 1 9\n",
      " ----- + ----- + -----\n",
      " 6 2 8 | 9 4 1 | 3 5 7\n",
      " 7 5 3 | 6 2 8 | 4 9 1\n",
      " 1 1 2 | 4 4 3 | 3 7 7\n",
      " ----- + ----- + -----\n",
      " 5 2 6 | 1 5 8 | 3 5 2\n",
      " 2 9 8 | 7 6 6 | 9 9 5\n",
      " 3 7 8 | 4 4 1 | 9 8 6\n",
      " - = -   - = -   - = - 62\t0:00:00.058838\n",
      "\n",
      " 2 3 1 | 5 7 9 | 8 4 6\n",
      " 9 4 6 | 8 1 2 | 5 7 3\n",
      " 8 7 5 | 4 6 3 | 2 1 9\n",
      " ----- + ----- + -----\n",
      " 6 2 8 | 9 4 1 | 3 5 7\n",
      " 7 5 3 | 6 2 8 | 4 9 1\n",
      " 1 9 2 | 4 2 3 | 3 7 7\n",
      " ----- + ----- + -----\n",
      " 5 1 1 | 1 6 8 | 3 5 2\n",
      " 2 9 8 | 7 5 6 | 9 9 6\n",
      " 3 7 8 | 4 4 8 | 5 4 6\n",
      " - = -   - = -   - = - 63\t0:00:00.061832\n",
      "\n",
      " 2 3 1 | 5 7 9 | 8 4 6\n",
      " 9 4 6 | 8 1 2 | 5 7 3\n",
      " 8 7 5 | 4 6 3 | 2 1 9\n",
      " ----- + ----- + -----\n",
      " 6 2 8 | 9 4 1 | 3 5 7\n",
      " 7 5 3 | 6 2 8 | 4 9 1\n",
      " 1 9 4 | 6 2 3 | 3 7 7\n",
      " ----- + ----- + -----\n",
      " 3 1 1 | 1 6 7 | 2 5 2\n",
      " 2 9 8 | 7 5 5 | 9 9 6\n",
      " 3 8 8 | 4 4 8 | 5 4 6\n",
      " - = -   - = -   - = - 64\t0:00:00.062836\n",
      "\n",
      " 2 3 1 | 5 7 9 | 8 4 6\n",
      " 9 4 6 | 8 1 2 | 5 7 3\n",
      " 8 7 5 | 4 6 3 | 2 1 9\n",
      " ----- + ----- + -----\n",
      " 6 2 8 | 9 4 1 | 3 5 7\n",
      " 7 5 3 | 6 2 8 | 4 9 1\n",
      " 1 9 4 | 7 2 3 | 3 8 7\n",
      " ----- + ----- + -----\n",
      " 3 1 6 | 1 6 7 | 2 5 2\n",
      " 4 9 8 | 7 5 5 | 9 9 6\n",
      " 3 8 8 | 4 4 5 | 2 1 6\n",
      " - = -   - = -   - = - 65\t0:00:00.063827\n",
      "\n",
      " 2 3 1 | 5 7 9 | 8 4 6\n",
      " 9 4 6 | 8 1 2 | 5 7 3\n",
      " 8 7 5 | 4 6 3 | 2 1 9\n",
      " ----- + ----- + -----\n",
      " 6 2 8 | 9 4 1 | 3 5 7\n",
      " 7 5 3 | 6 2 8 | 4 9 1\n",
      " 1 9 4 | 7 3 3 | 3 8 7\n",
      " ----- + ----- + -----\n",
      " 2 1 6 | 1 6 7 | 2 5 2\n",
      " 4 9 8 | 7 5 5 | 9 9 6\n",
      " 3 8 8 | 4 4 5 | 2 1 6\n",
      " - = -   - = -   - = - 66\t0:00:00.071807\n",
      "\n",
      " 2 3 1 | 5 7 9 | 8 4 6\n",
      " 9 4 6 | 8 1 2 | 5 7 3\n",
      " 8 7 5 | 4 6 3 | 2 1 9\n",
      " ----- + ----- + -----\n",
      " 6 2 8 | 9 4 1 | 3 5 7\n",
      " 7 5 3 | 6 2 8 | 4 9 1\n",
      " 1 9 4 | 7 3 5 | 3 8 7\n",
      " ----- + ----- + -----\n",
      " 2 1 6 | 1 6 7 | 2 5 2\n",
      " 4 9 8 | 7 5 3 | 9 9 6\n",
      " 3 8 8 | 4 4 5 | 2 1 6\n",
      " - = -   - = -   - = - 67\t0:00:00.073800\n",
      "\n",
      " 2 3 1 | 5 7 9 | 8 4 6\n",
      " 9 4 6 | 8 1 2 | 5 7 3\n",
      " 8 7 5 | 4 6 3 | 2 1 9\n",
      " ----- + ----- + -----\n",
      " 6 2 8 | 9 4 1 | 3 5 7\n",
      " 7 5 3 | 6 2 8 | 4 9 1\n",
      " 1 9 4 | 7 3 5 | 6 2 8\n",
      " ----- + ----- + -----\n",
      " 8 7 8 | 1 6 7 | 2 5 2\n",
      " 4 9 3 | 7 5 2 | 9 9 6\n",
      " 3 8 3 | 4 4 5 | 1 1 6\n",
      " - = -   - = -   - = - 71\t0:00:00.077790\n",
      "\n",
      " 2 3 1 | 5 7 9 | 8 4 6\n",
      " 9 4 6 | 8 1 2 | 5 7 3\n",
      " 8 7 5 | 4 6 3 | 2 1 9\n",
      " ----- + ----- + -----\n",
      " 6 2 8 | 9 4 1 | 3 5 7\n",
      " 7 5 3 | 6 2 8 | 4 9 1\n",
      " 1 9 4 | 7 3 5 | 6 2 8\n",
      " ----- + ----- + -----\n",
      " 5 7 8 | 9 8 7 | 2 5 2\n",
      " 4 9 3 | 7 6 2 | 9 1 6\n",
      " 3 8 3 | 4 4 5 | 1 1 6\n",
      " - = -   - = -   - = - 72\t0:00:00.079785\n",
      "\n",
      " 2 3 1 | 5 7 9 | 8 4 6\n",
      " 9 4 6 | 8 1 2 | 5 7 3\n",
      " 8 7 5 | 4 6 3 | 2 1 9\n",
      " ----- + ----- + -----\n",
      " 6 2 8 | 9 4 1 | 3 5 7\n",
      " 7 5 3 | 6 2 8 | 4 9 1\n",
      " 1 9 4 | 7 3 5 | 6 2 8\n",
      " ----- + ----- + -----\n",
      " 5 8 8 | 9 8 7 | 2 5 2\n",
      " 4 9 3 | 7 6 7 | 9 1 6\n",
      " 3 2 3 | 4 4 5 | 1 1 6\n",
      " - = -   - = -   - = - 73\t0:00:00.081789\n",
      "\n",
      " 2 3 1 | 5 7 9 | 8 4 6\n",
      " 9 4 6 | 8 1 2 | 5 7 3\n",
      " 8 7 5 | 4 6 3 | 2 1 9\n",
      " ----- + ----- + -----\n",
      " 6 2 8 | 9 4 1 | 3 5 7\n",
      " 7 5 3 | 6 2 8 | 4 9 1\n",
      " 1 9 4 | 7 3 5 | 6 2 8\n",
      " ----- + ----- + -----\n",
      " 5 8 9 | 9 8 7 | 2 5 2\n",
      " 4 9 3 | 7 6 7 | 3 1 6\n",
      " 3 2 4 | 8 4 5 | 1 1 6\n",
      " - = -   - = -   - = - 74\t0:00:00.085769\n",
      "\n",
      " 2 3 1 | 5 7 9 | 8 4 6\n",
      " 9 4 6 | 8 1 2 | 5 7 3\n",
      " 8 7 5 | 4 6 3 | 2 1 9\n",
      " ----- + ----- + -----\n",
      " 6 2 8 | 9 4 1 | 3 5 7\n",
      " 7 5 3 | 6 2 8 | 4 9 1\n",
      " 1 9 4 | 7 3 5 | 6 2 8\n",
      " ----- + ----- + -----\n",
      " 5 8 9 | 2 9 7 | 2 5 2\n",
      " 4 9 3 | 7 6 7 | 3 1 8\n",
      " 3 6 4 | 8 4 5 | 1 1 6\n",
      " - = -   - = -   - = - 75\t0:00:00.087763\n",
      "\n",
      " 2 3 1 | 5 7 9 | 8 4 6\n",
      " 9 4 6 | 8 1 2 | 5 7 3\n",
      " 8 7 5 | 4 6 3 | 2 1 9\n",
      " ----- + ----- + -----\n",
      " 6 2 8 | 9 4 1 | 3 5 7\n",
      " 7 5 3 | 6 2 8 | 4 9 1\n",
      " 1 9 4 | 7 3 5 | 6 2 8\n",
      " ----- + ----- + -----\n",
      " 5 8 7 | 3 9 4 | 2 5 2\n",
      " 2 6 3 | 7 6 7 | 9 9 8\n",
      " 3 4 4 | 8 1 5 | 1 1 6\n",
      " - = -   - = -   - = - 77\t0:00:00.121704\n",
      "\n",
      " 2 3 1 | 5 7 9 | 8 4 6\n",
      " 9 4 6 | 8 1 2 | 5 7 3\n",
      " 8 7 5 | 4 6 3 | 2 1 9\n",
      " ----- + ----- + -----\n",
      " 6 2 8 | 9 4 1 | 3 5 7\n",
      " 7 5 3 | 6 2 8 | 4 9 1\n",
      " 1 9 4 | 7 3 5 | 6 2 8\n",
      " ----- + ----- + -----\n",
      " 5 8 7 | 3 9 4 | 1 6 2\n",
      " 2 6 3 | 7 6 7 | 9 9 8\n",
      " 3 4 4 | 2 1 5 | 5 1 8\n",
      " - = -   - = -   - = - 81\t0:00:00.124698\n",
      "\n",
      " 2 3 1 | 5 7 9 | 8 4 6\n",
      " 9 4 6 | 8 1 2 | 5 7 3\n",
      " 8 7 5 | 4 6 3 | 2 1 9\n",
      " ----- + ----- + -----\n",
      " 6 2 8 | 9 4 1 | 3 5 7\n",
      " 7 5 3 | 6 2 8 | 4 9 1\n",
      " 1 9 4 | 7 3 5 | 6 2 8\n",
      " ----- + ----- + -----\n",
      " 5 8 7 | 3 9 4 | 1 6 2\n",
      " 3 6 9 | 7 1 7 | 6 9 8\n",
      " 3 4 4 | 2 5 5 | 2 1 8\n",
      " - = -   - = -   - = - 84\t0:00:00.127688\n",
      "\n",
      " 2 3 1 | 5 7 9 | 8 4 6\n",
      " 9 4 6 | 8 1 2 | 5 7 3\n",
      " 8 7 5 | 4 6 3 | 2 1 9\n",
      " ----- + ----- + -----\n",
      " 6 2 8 | 9 4 1 | 3 5 7\n",
      " 7 5 3 | 6 2 8 | 4 9 1\n",
      " 1 9 4 | 7 3 5 | 6 2 8\n",
      " ----- + ----- + -----\n",
      " 5 8 7 | 3 9 4 | 1 6 2\n",
      " 3 6 9 | 2 1 7 | 8 9 8\n",
      " 3 4 4 | 2 5 5 | 6 1 7\n",
      " - = -   - = -   - = - 85\t0:00:00.129649\n",
      "\n",
      " 2 3 1 | 5 7 9 | 8 4 6\n",
      " 9 4 6 | 8 1 2 | 5 7 3\n",
      " 8 7 5 | 4 6 3 | 2 1 9\n",
      " ----- + ----- + -----\n",
      " 6 2 8 | 9 4 1 | 3 5 7\n",
      " 7 5 3 | 6 2 8 | 4 9 1\n",
      " 1 9 4 | 7 3 5 | 6 2 8\n",
      " ----- + ----- + -----\n",
      " 5 8 7 | 3 9 4 | 1 6 2\n",
      " 3 6 9 | 2 8 7 | 8 9 2\n",
      " 3 4 1 | 6 5 5 | 4 1 7\n",
      " - = -   - = -   - = - 87\t0:00:00.137631\n",
      "\n",
      " 2 3 1 | 5 7 9 | 8 4 6\n",
      " 9 4 6 | 8 1 2 | 5 7 3\n",
      " 8 7 5 | 4 6 3 | 2 1 9\n",
      " ----- + ----- + -----\n",
      " 6 2 8 | 9 4 1 | 3 5 7\n",
      " 7 5 3 | 6 2 8 | 4 9 1\n",
      " 1 9 4 | 7 3 5 | 6 2 8\n",
      " ----- + ----- + -----\n",
      " 5 8 7 | 3 9 4 | 1 6 2\n",
      " 3 6 2 | 1 8 7 | 9 9 2\n",
      " 3 4 7 | 4 5 5 | 6 1 8\n",
      " - = -   - = -   - = - 88\t0:00:00.151592\n",
      "\n",
      " 2 3 1 | 5 7 9 | 8 4 6\n",
      " 9 4 6 | 8 1 2 | 5 7 3\n",
      " 8 7 5 | 4 6 3 | 2 1 9\n",
      " ----- + ----- + -----\n",
      " 6 2 8 | 9 4 1 | 3 5 7\n",
      " 7 5 3 | 6 2 8 | 4 9 1\n",
      " 1 9 4 | 7 3 5 | 6 2 8\n",
      " ----- + ----- + -----\n",
      " 5 8 7 | 3 9 4 | 1 6 2\n",
      " 3 6 2 | 1 5 7 | 9 8 4\n",
      " 7 3 2 | 9 1 5 | 4 6 8\n",
      " - = -   - = -   - = - 91\t0:00:00.161565\n",
      "\n",
      " 2 3 1 | 5 7 9 | 8 4 6\n",
      " 9 4 6 | 8 1 2 | 5 7 3\n",
      " 8 7 5 | 4 6 3 | 2 1 9\n",
      " ----- + ----- + -----\n",
      " 6 2 8 | 9 4 1 | 3 5 7\n",
      " 7 5 3 | 6 2 8 | 4 9 1\n",
      " 1 9 4 | 7 3 5 | 6 2 8\n",
      " ----- + ----- + -----\n",
      " 5 8 7 | 3 9 4 | 1 6 2\n",
      " 3 6 2 | 1 5 7 | 9 8 4\n",
      " 4 5 2 | 6 7 1 | 9 8 3\n",
      " - = -   - = -   - = - 92\t0:00:00.166577\n",
      "\n",
      " 2 3 1 | 5 7 9 | 8 4 6\n",
      " 9 4 6 | 8 1 2 | 5 7 3\n",
      " 8 7 5 | 4 6 3 | 2 1 9\n",
      " ----- + ----- + -----\n",
      " 6 2 8 | 9 4 1 | 3 5 7\n",
      " 7 5 3 | 6 2 8 | 4 9 1\n",
      " 1 9 4 | 7 3 5 | 6 2 8\n",
      " ----- + ----- + -----\n",
      " 5 8 7 | 3 9 4 | 1 6 2\n",
      " 3 6 2 | 1 5 7 | 9 8 4\n",
      " 4 1 2 | 5 9 6 | 7 8 3\n",
      " - = -   - = -   - = - 93\t0:00:00.178553\n",
      "\n",
      " 2 3 1 | 5 7 9 | 8 4 6\n",
      " 9 4 6 | 8 1 2 | 5 7 3\n",
      " 8 7 5 | 4 6 3 | 2 1 9\n",
      " ----- + ----- + -----\n",
      " 6 2 8 | 9 4 1 | 3 5 7\n",
      " 7 5 3 | 6 2 8 | 4 9 1\n",
      " 1 9 4 | 7 3 5 | 6 2 8\n",
      " ----- + ----- + -----\n",
      " 5 8 7 | 3 9 4 | 1 6 2\n",
      " 3 6 2 | 1 5 7 | 9 8 4\n",
      " 4 1 9 | 2 5 6 | 7 8 3\n",
      " - = -   - = -   - = - 95\t0:00:00.179550\n",
      "\n",
      " 2 3 1 | 5 7 9 | 8 4 6\n",
      " 9 4 6 | 8 1 2 | 5 7 3\n",
      " 8 7 5 | 4 6 3 | 2 1 9\n",
      " ----- + ----- + -----\n",
      " 6 2 8 | 9 4 1 | 3 5 7\n",
      " 7 5 3 | 6 2 8 | 4 9 1\n",
      " 1 9 4 | 7 3 5 | 6 2 8\n",
      " ----- + ----- + -----\n",
      " 5 8 7 | 3 9 4 | 1 6 2\n",
      " 3 6 2 | 1 5 7 | 9 8 4\n",
      " 4 1 9 | 2 8 3 | 7 6 5\n",
      " - = -   - = -   - = - 96\t0:00:00.184537\n",
      "\n",
      " 2 3 1 | 5 7 9 | 8 4 6\n",
      " 9 4 6 | 8 1 2 | 5 7 3\n",
      " 8 7 5 | 4 6 3 | 2 1 9\n",
      " ----- + ----- + -----\n",
      " 6 2 8 | 9 4 1 | 3 5 7\n",
      " 7 5 3 | 6 2 8 | 4 9 1\n",
      " 1 9 4 | 7 3 5 | 6 2 8\n",
      " ----- + ----- + -----\n",
      " 5 8 7 | 3 9 4 | 1 6 2\n",
      " 3 6 2 | 1 5 7 | 9 8 4\n",
      " 4 1 9 | 2 8 6 | 7 3 5\n",
      " - = -   - = -   - = - 100\t0:00:00.186531\n",
      "\n"
     ]
    }
   ],
   "source": [
    "test()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
